home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
fstab
/
fstab1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-27
|
8KB
|
382 lines
#include <string.h>
#include <stdlib.h>
#include "fstab.h"
#include "../paths.h"
#include "internal.h"
FSTAB_HELP_FILE help_fstab ("fstab");
static CONFIG_FILE f_fstab (ETC_FSTAB,help_fstab,CONFIGF_MANAGED);
PRIVATE void FSTAB_ENTRY::init()
{
valid = 0;
memset (&bool_opt,0,sizeof(bool_opt));
msdos_opt.uid = msdos_opt.gid = msdos_opt.perm = MSDOS_OPT_UNUSE;
nfs_opt.rsize = nfs_opt.wsize = NFS_OPT_UNUSE;
nfs_opt.soft = nfs_opt.bg = 0;
dumpfreq = fsckpriority = 1;
}
PUBLIC FSTAB_ENTRY::FSTAB_ENTRY()
{
init();
}
/*
Analyse the option string xxx,yyy,zzz=val,...
Some option are "known" by fsconf. Unknown one are left in
an "option" string editable by the user. The known one have
there own field in the FSTAB_ENTRY structure.
*/
PUBLIC void FSTAB_ENTRY::parseopt(char *opts)
{
char other[200];
other[0] = '\0';
while (*opts != '\0'){
char *debut = opts;
char *equal = "";
int seen_equal = 0;
while (1){
char *pt_carac = opts;
char carac = *opts++;
if (carac == '\0'){
opts--;
break;
}else if (carac == ','){
*pt_carac = '\0';
break;
}else if (carac == '='){
equal = opts;
*pt_carac = '\0';
seen_equal = 1;
}
}
if (strcmp(debut,"defaults")==0){
// Do nothing here. The keyword defaults
// is silently write back if no other option
// is specified.
}else if (strcmp(debut,"conv")==0){
msdos_opt.conv.setfrom(equal);
}else if (strcmp(debut,"uid")==0){
msdos_opt.uid = atoi(equal);
}else if (strcmp(debut,"gid")==0){
msdos_opt.gid = atoi(equal);
}else if (strcmp(debut,"perm")==0){
msdos_opt.perm = atoi(equal);
}else if (strcmp(debut,"noexec")==0){
bool_opt.noexec = 1;
}else if (strcmp(debut,"exec")==0){
bool_opt.noexec = 0;
}else if (strcmp(debut,"nosuid")==0){
bool_opt.nosuid = 1;
}else if (strcmp(debut,"suid")==0){
bool_opt.nosuid = 0;
}else if (strcmp(debut,"nodev")==0){
bool_opt.nodev = 1;
}else if (strcmp(debut,"dev")==0){
bool_opt.nodev = 0;
}else if (strcmp(debut,"user")==0){
bool_opt.user = 1;
bool_opt.nodev = 1;
bool_opt.noexec = 1;
bool_opt.nosuid = 1;
}else if (strcmp(debut,"ro")==0){
bool_opt.readonly = 1;
}else if (strcmp(debut,"rw")==0){
bool_opt.readonly = 0;
}else if (strcmp(debut,"noauto")==0){
bool_opt.noauto = 1;
}else if (strcmp(debut,"soft")==0){
nfs_opt.soft = 1;
}else if (strcmp(debut,"bg")==0){
nfs_opt.bg = 1;
}else if (strcmp(debut,"rsize")==0){
nfs_opt.rsize = atoi(equal);
}else if (strcmp(debut,"wsize")==0){
nfs_opt.wsize = atoi(equal);
}else if (strcmp(debut,"addr")!=0){
// This is the other option still unknown by linuxconf
// note that the simili addr option used by NFS in /etc/mtab
// is ignored.
if (other[0] != '\0') strcat (other,",");
strcat (other,debut);
if (seen_equal){
strcat (other,"=");
strcat (other,equal);
}
}
}
options.setfrom (other);
}
/*
Build an FSTAB_ENTRY from a line of the /etc/fstab file
*/
PUBLIC FSTAB_ENTRY::FSTAB_ENTRY (const char *line)
{
init();
line = str_skip (line);
if (*line != '\0'){
if (*line == '#'){
comment.setfrom(line);
}else{
char buf[1000];
strcpy (buf,line);
char *pt1 = strtok (buf," \t");
char *pt2 = strtok (NULL," \t");
char *pt3 = strtok (NULL," \t");
char *pt4 = strtok (NULL," \t");
char *pt5 = strtok (NULL," \t");
char *pt6 = strtok (NULL," \t");
if (pt4 != NULL){
source.setfrom(pt1);
mpoint.setfrom(pt2);
type.setfrom (pt3);
parseopt (pt4);
if (pt5 != NULL) dumpfreq = atoi(pt5);
if (pt6 != NULL) fsckpriority = atoi(pt6);
valid = 1;
}else{
comment.setfrom(str_skip(line));
}
}
}
}
static void opt_put_if (
char *out,
char bool_opt,
const char *name,
int &was_written)
{
if (bool_opt){
if (was_written) strcat (out,",");
was_written = 1;
strcat (out,name);
}
}
static void opt_put_if (
char *out,
char bool_opt,
const char *noname,
const char *name,
int &was_written)
{
if (was_written) strcat (out,",");
was_written = 1;
strcat (out,bool_opt ? noname : name);
}
static void opt_put_if (
char *out,
int value,
const char *name,
int &was_written)
{
if (value != MSDOS_OPT_UNUSE){
if (was_written) strcat (out,",");
was_written = 1;
char buf[100];
sprintf (buf,"%s=%d",name,value);
strcat (out,buf);
}
}
static void opt_put_if (
char *out,
const char *value,
const char *name,
int &was_written)
{
if (value[0] != '\0'){
if (was_written) strcat (out,",");
was_written = 1;
char buf[100];
sprintf (buf,"%s=%s",name,value);
strcat (out,buf);
}
}
/*
Format all the mount option in a string suitable for the mount command
if tosave != 0, it also adds the options only meaningful in /etc/fstab
(user,noauto,...)
*/
PUBLIC void FSTAB_ENTRY::format_opt(int tosave, char *str) const
{
int one = 0;
str[0] = '\0';
if (tosave) opt_put_if (str,bool_opt.user,"user",one);
opt_put_if (str,bool_opt.noexec,"noexec","exec",one);
opt_put_if (str,bool_opt.nodev,"nodev","dev",one);
opt_put_if (str,bool_opt.nosuid,"nosuid","suid",one);
opt_put_if (str,bool_opt.readonly,"ro","rw",one);
if (tosave) opt_put_if (str,bool_opt.noauto,"noauto",one);
opt_put_if (str,msdos_opt.conv.get(),"conv",one);
opt_put_if (str,msdos_opt.uid,"uid",one);
opt_put_if (str,msdos_opt.gid,"gid",one);
opt_put_if (str,msdos_opt.perm,"perm",one);
opt_put_if (str,nfs_opt.bg,"bg",one);
opt_put_if (str,nfs_opt.soft,"soft",one);
opt_put_if (str,nfs_opt.rsize,"rsize",one);
opt_put_if (str,nfs_opt.wsize,"wsize",one);
if (!options.is_empty()){
if (one) strcat (str,",");
strcat (str,options.get());
}else if (!one){
if (tosave) strcpy (str,"defaults");
}
}
/*
Write an entry into /etc/fstab
*/
PUBLIC void FSTAB_ENTRY::print (FILE *fout) const
{
if (valid){
fprintf (fout,"%s\t%s\t%s\t",source.get(),mpoint.get()
,type.get());
char str[200];
format_opt (1,str);
fprintf (fout," %s %d %d",str,dumpfreq,fsckpriority);
}else{
fputs (comment.get(),fout);
}
fputc ('\n',fout);
}
/*
Return != 0 if this entry is ok (not a comment).
*/
PUBLIC int FSTAB_ENTRY::is_valid() const
{
return valid;
}
/*
Tell if this mount should be done at boot time.
*/
PUBLIC int FSTAB_ENTRY::is_auto()
{
return !bool_opt.noauto;
}
/*
Return != 0 if the entry describe a mount of a remote volume
either with NFS or SMBFS.
*/
PUBLIC int FSTAB_ENTRY::is_remote() const
{
return type.cmp("nfs")==0 || type.cmp("smbfs")==0;
}
/*
Return != 0 if the entry describe a swap file or partition.
*/
PUBLIC int FSTAB_ENTRY::is_swap() const
{
return type.cmp("swap")==0;
}
/*
Return the file system type ID
*/
PUBLIC FSTAB_ENTRY_TYPE FSTAB_ENTRY::gettype() const
{
FSTAB_ENTRY_TYPE ret = FSTAB_ENTRY_LOCAL;
if (is_swap()){
ret = FSTAB_ENTRY_SWAP;
}else if (type.cmp("nfs")==0){
ret = FSTAB_ENTRY_NFS;
}else if (type.cmp("smbfs")==0){
ret = FSTAB_ENTRY_SAMBA;
}else if (type.cmp("proc")==0){
ret = FSTAB_ENTRY_PROC;
}
return ret;
}
/*
Return the file systeme type (ascii).
*/
PUBLIC const char *FSTAB_ENTRY::getfs() const
{
return type.get();
}
/*
Return the source of the mount (either the device or the remote volume)
*/
PUBLIC const char *FSTAB_ENTRY::getsource() const
{
return source.get();
}
/*
Record a new device / remote volume for a FSTAB_ENTRY
*/
PUBLIC void FSTAB_ENTRY::setsource(const char *path)
{
source.setfrom (path);
setmodified();
}
/*
Return the mount point
*/
PUBLIC const char *FSTAB_ENTRY::getmpoint() const
{
return mpoint.get();
}
/*
Return the comment of the entry
*/
PUBLIC const char *FSTAB_ENTRY::getcomment()
{
return comment.get();
}
PUBLIC FSTAB::FSTAB ()
{
FILE *fin = f_fstab.fopen("r");
if (fin != NULL){
char buf[1000];
while (fgets_cont(buf,sizeof(buf)-1,fin) != -1){
add (new FSTAB_ENTRY(buf));
}
fclose (fin);
}
rstmodified();
}
/*
Return one entry of the fstab file.
Returne NULL if the entry is out of range.
*/
PUBLIC FSTAB_ENTRY *FSTAB_GEN::getitem(int no)
{
return (FSTAB_ENTRY*)ARRAY::getitem(no);
}
/*
Write a /etc/fstab file
Return -1 if any error.
*/
PUBLIC int FSTAB::write ()
{
int ret = -1;
FILE *fout = f_fstab.fopen ("w");
if (fout != NULL){
ret = 0;
for (int i=0; i<nb; i++) getitem(i)->print (fout);
fclose (fout);
}
return ret;
}
#ifdef TEST
int main (int argc, char *argv[])
{
FSTAB fs;
fs.write();
return 0;
}
#endif